package seedpod.webapp.controller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import seedpod.exceptions.SeedpodException;
import seedpod.model.AVPair;
import seedpod.model.InstanceRelationship;
import seedpod.model.NoObjectFoundException;
import seedpod.model.ProtegeValueType;
import seedpod.model.SeedpodDO;
import seedpod.model.ValueSetRelationship;
import seedpod.util.Util;
import seedpod.webapp.LimsSession;
import seedpod.webapp.view.seedpodwidgets.LimsWidget;
import seedpod.webapp.view.seedpodwidgets.LimsWidgetFactory;

public class ActionInPlaceEditor extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	public void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		LimsSession limsSession = new LimsSession( request );

		// determine whether to save data after submit or to display editor form
		String submit = request.getParameter( "submitInPlaceEdit" );
		boolean saveData = submit != null && submit.equalsIgnoreCase( "save" );

		// gather input parameters
		String clsName = request.getParameter( "cls" );
		String attributeName = request.getParameter( "slot" );
		String oidSt = request.getParameter( "oid" );
		Integer oid = 0;
		String errorMessage = "";
		if ( oidSt != null ) oid = Integer.parseInt( oidSt );

		// Initialize object and the attribute-value-pair
		SeedpodDO obj = limsSession.getSessionCachedObject( clsName, oid );
		if ( obj == null ) try {
			obj = new SeedpodDO( clsName, oid, limsSession.getDataManager() );
			obj.retrieveById();
		} catch (NoObjectFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SeedpodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// get AVPair for the attribute
		AVPair avPair = obj.getAttributeValue( attributeName );

		// If the action is to submit data, update the object and save, otherwise, display editor
		if ( saveData ) {
			String[] submittedValues;

			// Multiple value inputs
			if ( avPair.getAttribute().isMultiple() ) {
				submittedValues = request.getParameterValues( avPair.genRefId() );

				// handling relationships
				if ( avPair.getAttribute().isRelationship() ) {

					// Instance relationships
					if ( avPair.getAttribute().getProtegeValueType().equals( ProtegeValueType.Instance ) ) {
						System.out.println( "Saving a instance relationship " );

						InstanceRelationship rel = (InstanceRelationship)avPair.getValue();
						if ( rel == null ) rel = new InstanceRelationship( avPair.getAttribute(), obj );
						for ( String s : submittedValues )
							rel.addRelationship( obj.getOid(), Integer.parseInt( s ) );
						// TODO 
						rel.save();
					} 
					
					// Value set relations
					else {
						System.out.println( "Saving a Value Set... " );

						ValueSetRelationship valSet = (ValueSetRelationship)avPair.getValue();
						if ( valSet == null ) valSet = new ValueSetRelationship( avPair.getAttribute(), obj );

						for ( String s : submittedValues )
							valSet.addTarget( s );
						
						// TODO
						valSet.save();
					}
				}
			}

			// Single value input
			else {
				Object submittedValue = request.getParameter( avPair.genRefId() );
				avPair.setValue( submittedValue );
			}

			System.out.println( "<br> slot: " + attributeName + " =" + avPair.getValue().toString() );

			try {
				// Save the new object in the database
				obj.makePersist();

				// Update the attribute value display
				LimsWidget viewWidget = LimsWidgetFactory.getViewWidget( avPair );
				out.println( viewWidget.doView() );

				// Save the object back into session
				limsSession.setAttribute( Util.getSeedpodInternalId( clsName, oid ), obj );
			} catch (SeedpodException e) {
				saveData = false; // allow the logic to do the next step again
				errorMessage = e.getMessage();
				response.sendError( HttpServletResponse.SC_EXPECTATION_FAILED, errorMessage );
			}

		}
	}
}
